/* vim: set ft=cpp fdm=marker et: */

%%
headers

static void phpg_text_tag_table_foreach_func_marshal (GtkTextTagTable *table, gpointer data);
static gboolean phpg_text_iter_char_predicate_func_marshal (gunichar ch, gpointer data);

%% {{{ ignores
%%
ignore
    gtk_text_view_new
%% }}}

%% {{{ GtkTextBuffer

%%
override gtk_text_buffer_get_bounds
PHP_METHOD
{
    GtkTextIter start, end;
    zval *php_start = NULL;
    zval *php_end = NULL;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
        return;

    gtk_text_buffer_get_bounds(GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr)), &start, &end);

    phpg_gboxed_new(&php_start, GTK_TYPE_TEXT_ITER, &start, TRUE, TRUE TSRMLS_CC);
    phpg_gboxed_new(&php_end, GTK_TYPE_TEXT_ITER, &end, TRUE, TRUE TSRMLS_CC);

    php_gtk_build_value(&return_value, "(NN)", php_start, php_end);
}

%%
override gtk_text_buffer_get_selection_bounds
PHP_METHOD
{
    GtkTextIter start, end;
    zval *php_start = NULL;
    zval *php_end = NULL;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
        return;

    if (gtk_text_buffer_get_selection_bounds(GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr)), &start, &end)) {
        phpg_gboxed_new(&php_start, GTK_TYPE_TEXT_ITER, &start, TRUE, TRUE TSRMLS_CC);
        phpg_gboxed_new(&php_end, GTK_TYPE_TEXT_ITER, &end, TRUE, TRUE TSRMLS_CC);

        php_gtk_build_value(&return_value, "(NN)", php_start, php_end);
    } else {
        RETURN_FALSE;
    }
}

%%
override gtk_text_buffer_get_start_iter
PHP_METHOD
{
    GtkTextIter iter;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
        return;

    gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr)), &iter);
    phpg_gboxed_new(&return_value, GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE TSRMLS_CC);
}

%%
override gtk_text_buffer_get_end_iter
PHP_METHOD
{
    GtkTextIter iter;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
        return;

    gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr)), &iter);
    phpg_gboxed_new(&return_value, GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE TSRMLS_CC);
}

%%
add-arginfo GtkTextBuffer get_iter_at_line
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, line_number)
ZEND_END_ARG_INFO();

%%
override gtk_text_buffer_get_iter_at_line
PHP_METHOD
{
    GtkTextIter iter;
    int line_number;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "i", &line_number))
        return;

    gtk_text_buffer_get_iter_at_line(GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr)), &iter, line_number);
    phpg_gboxed_new(&return_value, GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE TSRMLS_CC);
}

%%
override gtk_text_buffer_get_iter_at_mark
PHP_METHOD
{
    GtkTextIter iter;
    zval *mark;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "O", &mark, gtktextmark_ce))
        return;

    gtk_text_buffer_get_iter_at_mark(GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr)), &iter,
                                     GTK_TEXT_MARK(PHPG_GOBJECT(mark)));
    phpg_gboxed_new(&return_value, GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE TSRMLS_CC);
}

%%
override gtk_text_buffer_get_iter_at_child_anchor
PHP_METHOD
{
    GtkTextIter iter;
    zval *anchor;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "O", &anchor, gtktextchildanchor_ce))
        return;

    gtk_text_buffer_get_iter_at_child_anchor(GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr)), &iter,
                                     GTK_TEXT_CHILD_ANCHOR(PHPG_GOBJECT(anchor)));
    phpg_gboxed_new(&return_value, GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE TSRMLS_CC);
}

%%
add-arginfo GtkTextBuffer get_iter_at_line_offset
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, line_number)
    ZEND_ARG_INFO(0, char_offset)
ZEND_END_ARG_INFO();

%%
override gtk_text_buffer_get_iter_at_line_offset
PHP_METHOD
{
    GtkTextIter iter;
    int line_number, char_offset;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "ii", &line_number, &char_offset))
        return;

    gtk_text_buffer_get_iter_at_line_offset(GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr)), &iter, line_number, char_offset);
    phpg_gboxed_new(&return_value, GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE TSRMLS_CC);
}

%%
add-arginfo GtkTextBuffer get_iter_at_line_index
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, line_number)
    ZEND_ARG_INFO(0, byte_offset)
ZEND_END_ARG_INFO();

%%
override gtk_text_buffer_get_iter_at_line_index
PHP_METHOD
{
    GtkTextIter iter;
    int line_number, byte_offset = 0;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "ii", &line_number, byte_offset))
        return;

    gtk_text_buffer_get_iter_at_line_index(GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr)), &iter, line_number, byte_offset);
    phpg_gboxed_new(&return_value, GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE TSRMLS_CC);
}

%%
add-arginfo GtkTextBuffer get_iter_at_offset
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, char_offset)
ZEND_END_ARG_INFO();

%%
override gtk_text_buffer_get_iter_at_offset
PHP_METHOD
{
    GtkTextIter iter;
    int char_offset;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "i", &char_offset))
        return;

    gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr)), &iter, char_offset);
    phpg_gboxed_new(&return_value, GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE TSRMLS_CC);
}

%%
add-arginfo GtkTextBuffer set_text
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, text)
ZEND_END_ARG_INFO();

%%
override gtk_text_buffer_set_text
PHP_METHOD
{
    char *text;
    int text_len;
    zend_bool free_text;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "u#", &text, &text_len, &free_text))
        return;

    gtk_text_buffer_set_text(GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr)), text, text_len);

    if (free_text) g_free(text);
}

%%
override gtk_text_buffer_insert_with_tags_by_name
PHP_METHOD
{
    zval *tags = NULL, *php_iter, **tag;
    char *text;
    int text_len, start_offset;
    GtkTextIter *iter, start;
    GtkTextBuffer *buffer;
    zend_bool free_text;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_args_quiet(ZEND_NUM_ARGS(), "Ou#a", &php_iter, gtktextiter_ce,
                                  &text, &text_len, &free_text, &tags) &&
        !php_gtk_parse_varargs(ZEND_NUM_ARGS(), 2, &tags, "Ou#", &php_iter, gtktextiter_ce,
                               &text, &text_len, &free_text)) {
        return;
    }

    iter = (GtkTextIter *) PHPG_GBOXED(php_iter);
    buffer = GTK_TEXT_BUFFER(PHPG_GOBJECT(this_ptr));

    start_offset = gtk_text_iter_get_offset(iter);
    gtk_text_buffer_insert(buffer, iter, text, text_len);
    gtk_text_buffer_get_iter_at_offset(buffer, &start, start_offset);

    if (tags) {
        for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(tags));
             zend_hash_get_current_data(Z_ARRVAL_P(tags), (void **) &tag) == SUCCESS;
             zend_hash_move_forward(Z_ARRVAL_P(tags))) {

            convert_to_string_ex(tag);
            gtk_text_buffer_apply_tag_by_name(buffer, Z_STRVAL_PP(tag), &start, iter);
        }
    }
}

%% }}}

%% {{{ GtkTextIter

%%
override gtk_text_iter_get_char
PHP_METHOD
{
    gunichar ichar;
    gint len;
    gchar *ret = safe_emalloc(6, sizeof(gchar *), 0);
    gchar *cp_ret;
    gsize cp_len;
    zend_bool free_result = FALSE;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
        return;

    ichar = gtk_text_iter_get_char((GtkTextIter *)PHPG_GBOXED(this_ptr));

    if (ichar) {
        len = g_unichar_to_utf8(ichar, ret);
        cp_ret = phpg_from_utf8(ret, len, &cp_len, &free_result TSRMLS_CC);

        if (cp_ret) {
            RETVAL_STRINGL((char *)cp_ret, cp_len, 1);
        } else {
            php_error(E_WARNING, "%s::%s(): could not convert return value from UTF-8", get_active_class_name(NULL TSRMLS_CC), get_active_function_name(TSRMLS_C));
        }

        if (free_result)
            g_free(cp_ret);
        else
            RETVAL_STRINGL((char *)ichar, len, 1);
    } else {
        RETVAL_NULL();
    }

    efree(ret);
}

%%
override gtk_text_iter_get_tags
PHP_METHOD
{
    GSList *tags, *tag;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
        return;

    tags = gtk_text_iter_get_tags((GtkTextIter *)PHPG_GBOXED(this_ptr));

    array_init(return_value);
    for (tag = tags; tag; tag = tag->next) {
        zval *php_tag = NULL;
        phpg_gobject_new(&php_tag, G_OBJECT(tag->data) TSRMLS_CC);
        add_next_index_zval(return_value, php_tag);
    }
    g_slist_free(tags);
}

%%
override gtk_text_iter_get_marks
PHP_METHOD
{
    GSList *marks, *mark;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
        return;

    marks = gtk_text_iter_get_marks((GtkTextIter *)PHPG_GBOXED(this_ptr));

    array_init(return_value);
    for (mark = marks; mark; mark = mark->next) {
        zval *php_mark = NULL;
        phpg_gobject_new(&php_mark, G_OBJECT(mark->data) TSRMLS_CC);
        add_next_index_zval(return_value, php_mark);
    }
    g_slist_free(marks);
}

%%
override gtk_text_iter_get_toggled_tags
PHP_METHOD
{
    GSList *tags, *tag;
    zend_bool toggled_on = 1;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "b", &toggled_on))
        return;

    tags = gtk_text_iter_get_toggled_tags((GtkTextIter *)PHPG_GBOXED(this_ptr), toggled_on);

    array_init(return_value);
    for (tag = tags; tag; tag = tag->next) {
        zval *php_tag = NULL;
        phpg_gobject_new(&php_tag, G_OBJECT(tag->data) TSRMLS_CC);
        add_next_index_zval(return_value, php_tag);
    }
    g_slist_free(tags);
}

%%
add-arginfo GtkTextIter forward_find_char 
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, callback)
    ZEND_ARG_OBJ_INFO(0, iter, GtkTextIter, 1)
ZEND_END_ARG_INFO();

%%
override gtk_text_iter_forward_find_char

static gboolean phpg_text_iter_char_predicate_func_marshal (gunichar ch, gpointer data)
{
    phpg_cb_data_t *cbd = (phpg_cb_data_t *) data;
    zval *retval = NULL;
    zval ***args = NULL;
    int n_args = 0; gint length;
    char *callback_name;
    zval *php_char;
    gchar *param = safe_emalloc(6, sizeof(gchar *), 0);
    gchar *cp_ret; gsize cp_len;
    zend_bool toreturn, free_result = FALSE;

#ifdef ZTS
    TSRMLS_D = cbd->TSRMLS_C;
#endif

    if (!zend_is_callable(cbd->callback, 0, &callback_name PHPGTK_ZEND_IS_CALLABLE)) {
        php_error(E_WARNING, "Unable to invoke callback '%s' specified in %s on line %ld", callback_name, cbd->src_filename, cbd->src_lineno);
        efree(callback_name);
        return 0;
    }

    length = g_unichar_to_utf8(ch, param);
    cp_ret = phpg_from_utf8(param, length, &cp_len, &free_result TSRMLS_CC);
    
    if (cp_ret) {
        args = php_gtk_hash_as_array_offset(cbd->user_args, 1, &n_args);
        MAKE_STD_ZVAL(php_char);
        ZVAL_STRINGL(php_char, (char*)cp_ret, cp_len, 1);
        args[0] = &php_char;
    } else {
        php_error(E_WARNING, "%s::%s(): could not convert return value from UTF-8", get_active_class_name(NULL TSRMLS_CC), get_active_function_name(TSRMLS_C));
        return FALSE;
    }

    if (free_result)
        g_free(cp_ret);

    call_user_function_ex(EG(function_table), NULL, cbd->callback, &retval, n_args, args, 0, NULL TSRMLS_CC);

    if (retval) {
        toreturn = zend_is_true(retval);
        zval_ptr_dtor(&retval);
    } else {
        toreturn = FALSE;
    }

    phpg_handle_marshaller_exception(TSRMLS_C);

    efree(callback_name);
    efree(args);

    return toreturn;
}

PHP_METHOD
{
    zval *php_callback, *extra, *limit_iter = NULL;
    phpg_cb_data_t *cb_data;
    GtkTextCharPredicate callback;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_varargs(ZEND_NUM_ARGS(), 2, &extra, "VN", &php_callback, &limit_iter, gtktextiter_ce))
        return;

    if (php_callback) {
        if (Z_TYPE_P(php_callback) == IS_NULL) {
            php_error(E_WARNING, "%s::%s(): You must specify a callback!", get_active_class_name(NULL TSRMLS_CC), get_active_function_name(TSRMLS_C));
            return;
        } else {
            zval_add_ref(&php_callback);
            cb_data  = phpg_cb_data_new(php_callback, extra TSRMLS_CC);
            callback = (GtkTextCharPredicate)phpg_text_iter_char_predicate_func_marshal;
        }
    }

    if (Z_TYPE_P(limit_iter) != IS_NULL)
        gtk_text_iter_forward_find_char((GtkTextIter *)PHPG_GBOXED(this_ptr),
                                            callback, cb_data, (GtkTextIter *)PHPG_GBOXED(limit_iter));
    else
        gtk_text_iter_forward_find_char((GtkTextIter *)PHPG_GBOXED(this_ptr),
                                            callback, cb_data, NULL); 
}

%%
add-arginfo GtkTextIter backward_find_char 
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_OBJ_INFO(0, iter, GtkTextIter, 1)
    ZEND_ARG_INFO(0, callback)
ZEND_END_ARG_INFO();

%%
override gtk_text_iter_backward_find_char
PHP_METHOD
{
    zval *php_callback, *extra, *limit_iter = NULL;
    phpg_cb_data_t *cb_data;
    GtkTextCharPredicate callback;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_varargs(ZEND_NUM_ARGS(), 2, &extra, "VN", &php_callback, &limit_iter, gtktextiter_ce))
        return;

    if (php_callback) {
        if (Z_TYPE_P(php_callback) == IS_NULL) {
            php_error(E_WARNING, "%s::%s(): You must specify a callback!", get_active_class_name(NULL TSRMLS_CC), get_active_function_name(TSRMLS_C));
            return;
        } else {
            zval_add_ref(&php_callback);
            cb_data  = phpg_cb_data_new(php_callback, extra TSRMLS_CC);
            callback = (GtkTextCharPredicate)phpg_text_iter_char_predicate_func_marshal;
        }
    }

    if (Z_TYPE_P(limit_iter) != IS_NULL)
        gtk_text_iter_backward_find_char((GtkTextIter *)PHPG_GBOXED(this_ptr),
                                            callback, cb_data, (GtkTextIter *)PHPG_GBOXED(limit_iter));
    else
        gtk_text_iter_backward_find_char((GtkTextIter *)PHPG_GBOXED(this_ptr),
                                            callback, cb_data, NULL); 
}

%% }}}

%% {{{ GtkTextChildAnchor

%%
override gtk_text_child_anchor_get_widgets
PHP_METHOD
{
    GList *widgets;
    gint i, len;
    zval *php_item = NULL;

    NOT_STATIC_METHOD();
    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
        return;

    widgets = gtk_text_child_anchor_get_widgets(GTK_TEXT_CHILD_ANCHOR(PHPG_GOBJECT(this_ptr)));
    len = g_list_length(widgets);

    array_init(return_value);
    for (i = 0; i < len; i++) {
        MAKE_STD_ZVAL(php_item);
        phpg_gobject_new(&php_item, (GObject *)g_list_nth_data(widgets, i) TSRMLS_CC);
        add_next_index_zval(return_value, php_item);
    }

    g_list_free(widgets);
}

%% }}}

%% {{{ GtkTextTagTable

%%
add-arginfo GtkTextTagTable for_each
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, callback)
ZEND_END_ARG_INFO();

%%
add GtkTextTagTable for_each
static void phpg_text_tag_table_foreach_func_marshal(GtkTextTagTable *table, gpointer data)
{
    phpg_cb_data_t *cbd = (phpg_cb_data_t *) data;
    zval *retval = NULL;
    zval ***args = NULL;
    int n_args = 0;
    char *callback_name;
    zval *php_table = NULL;

#ifdef ZTS
    TSRMLS_D = cbd->TSRMLS_C;
#endif

    if (!zend_is_callable(cbd->callback, 0, &callback_name PHPGTK_ZEND_IS_CALLABLE)) {
        php_error(E_WARNING, "Unable to invoke callback '%s' specified in %s on line %ld", callback_name, cbd->src_filename, cbd->src_lineno);
        efree(callback_name);
        return;
    }

    phpg_gobject_new(&php_table,       (GObject*)table       TSRMLS_CC);

    args = php_gtk_hash_as_array_offset(cbd->user_args, 1, &n_args);
    args[0] = &php_table;

    call_user_function_ex(EG(function_table), NULL, cbd->callback, &retval, n_args, args, 0, NULL TSRMLS_CC);

    zval_ptr_dtor(&php_table);

    if (retval) {
        zval_ptr_dtor(&retval);
    }

    phpg_handle_marshaller_exception(TSRMLS_C);

    efree(callback_name);
    efree(args);
}

PHP_METHOD
{
    zval *php_callback, *extra;
    phpg_cb_data_t *cb_data;
    GtkTextTagTableForeach callback;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_varargs(ZEND_NUM_ARGS(), 1, &extra, "V", &php_callback))
        return;

    zval_add_ref(&php_callback);
    cb_data  = phpg_cb_data_new(php_callback, extra TSRMLS_CC);
    callback = (GtkTextTagTableForeach)phpg_text_tag_table_foreach_func_marshal;

    gtk_text_tag_table_foreach(GTK_TEXT_TAG_TABLE(PHPG_GOBJECT(this_ptr)), callback, cb_data);
    phpg_cb_data_destroy(cb_data);
}


%% }}}

%% {{{ GtkTextView

%%
add-arginfo GtkTextView buffer_to_window_coords
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, window_type)
    ZEND_ARG_INFO(0, buffer_x)
    ZEND_ARG_INFO(0, buffer_y)
ZEND_END_ARG_INFO();

%%
override gtk_text_view_buffer_to_window_coords
PHP_METHOD
{
    gint buffer_x, buffer_y, window_x, window_y;
    GtkTextWindowType win_type;
    zval *php_win_type = NULL;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "Vii", &php_win_type, &buffer_x, &buffer_y))
        return;

    if (php_win_type && phpg_gvalue_get_enum(GTK_TYPE_TEXT_WINDOW_TYPE, php_win_type, (gint *)&win_type) == FAILURE)
        return;

    gtk_text_view_buffer_to_window_coords(GTK_TEXT_VIEW(PHPG_GOBJECT(this_ptr)), win_type, buffer_x, buffer_y, &window_x, &window_y);
    php_gtk_build_value(&return_value, "(ii)", window_x, window_y);
}


%%
add-arginfo GtkTextView get_iter_at_location
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, x)
    ZEND_ARG_INFO(0, y)
ZEND_END_ARG_INFO();

%%
override gtk_text_view_get_iter_at_location
PHP_METHOD
{
    gint x, y;
    GtkTextIter iter;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "ii", &x, &y))
        return;

    gtk_text_view_get_iter_at_location(GTK_TEXT_VIEW(PHPG_GOBJECT(this_ptr)), &iter, x, y);

    phpg_gboxed_new(&return_value, GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE TSRMLS_CC);
}


%%
add-arginfo GtkTextView get_iter_at_position
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, x)
    ZEND_ARG_INFO(0, y)
ZEND_END_ARG_INFO();

%%
override gtk_text_view_get_iter_at_position
PHP_METHOD
{
    gint x, y, trailing;
    zval *php_iter = NULL;
    GtkTextIter iter;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "ii", &x, &y))
        return;

    gtk_text_view_get_iter_at_position(GTK_TEXT_VIEW(PHPG_GOBJECT(this_ptr)), &iter, &trailing, x, y);

    phpg_gboxed_new(&php_iter, GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE TSRMLS_CC);

    php_gtk_build_value(&return_value, "(Ni)", php_iter, trailing);
}


%%
add-arginfo GtkTextView get_iter_location
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_OBJ_INFO(0, iter, GtkTextIter, 0)
ZEND_END_ARG_INFO();

%%
override gtk_text_view_get_iter_location
PHP_METHOD
{
    zval *php_iter = NULL;
    GtkTextIter *iter = NULL;
    GdkRectangle rect;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "O", &php_iter, gtktextiter_ce))
        return;

    if (php_iter && IS_OBJECT == Z_TYPE_P(php_iter)) {
        iter = (GtkTextIter *) PHPG_GBOXED(php_iter);
    }

    gtk_text_view_get_iter_location(GTK_TEXT_VIEW(PHPG_GOBJECT(this_ptr)), iter, &rect);
    phpg_gboxed_new(&return_value, GDK_TYPE_RECTANGLE, &rect, TRUE, TRUE TSRMLS_CC);
}


%%
add-arginfo GtkTextView get_line_at_y
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, y)
ZEND_END_ARG_INFO();

%%
override gtk_text_view_get_line_at_y
PHP_METHOD
{
    gint y, line_top;
    zval *php_iter = NULL;
    GtkTextIter iter;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "i", &y))
        return;

    gtk_text_view_get_line_at_y(GTK_TEXT_VIEW(PHPG_GOBJECT(this_ptr)), &iter, y, &line_top);

    phpg_gboxed_new(&php_iter, GTK_TYPE_TEXT_ITER, &iter, TRUE, TRUE TSRMLS_CC);

    php_gtk_build_value(&return_value, "(Ni)", php_iter, line_top);
}


%%
add-arginfo GtkTextView get_line_yrange
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_OBJ_INFO(0, iter, GtkTextIter, 0)
ZEND_END_ARG_INFO();

%%
override gtk_text_view_get_line_yrange
PHP_METHOD
{
    zval *php_iter = NULL;
    GtkTextIter *iter = NULL;
    gint y, height;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "O", &php_iter, gtktextiter_ce))
        return;

    if (php_iter && IS_OBJECT == Z_TYPE_P(php_iter)) {
        iter = (GtkTextIter *) PHPG_GBOXED(php_iter);
    }

    gtk_text_view_get_line_yrange(GTK_TEXT_VIEW(PHPG_GOBJECT(this_ptr)), iter, &y, &height);
    php_gtk_build_value(&return_value, "(ii)", y, height);
}

%%
override gtk_text_view_get_visible_rect
PHP_METHOD
{
    GdkRectangle rect;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), ""))
        return;

    gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(PHPG_GOBJECT(this_ptr)), &rect);
    phpg_gboxed_new(&return_value, GDK_TYPE_RECTANGLE, &rect, TRUE, TRUE TSRMLS_CC);
}

%%
add-arginfo GtkTextView window_to_buffer_coords
PHPGTK_ARG_INFO_STATIC
ZEND_BEGIN_ARG_INFO(ARGINFO_NAME, 0)
    ZEND_ARG_INFO(0, window_type)
    ZEND_ARG_INFO(0, window_x)
    ZEND_ARG_INFO(0, window_y)
ZEND_END_ARG_INFO();

%%
override gtk_text_view_window_to_buffer_coords
PHP_METHOD
{
    gint window_x, window_y, buffer_x, buffer_y;
    GtkTextWindowType win_type;
    zval *php_win_type = NULL;

    NOT_STATIC_METHOD();

    if (!php_gtk_parse_args(ZEND_NUM_ARGS(), "Vii", &php_win_type, &window_x, &window_y))
        return;

    if (php_win_type && phpg_gvalue_get_enum(GTK_TYPE_TEXT_WINDOW_TYPE, php_win_type, (gint *)&win_type) == FAILURE)
        return;

    gtk_text_view_window_to_buffer_coords(GTK_TEXT_VIEW(PHPG_GOBJECT(this_ptr)), win_type, window_x, window_y, &buffer_x, &buffer_y);
    php_gtk_build_value(&return_value, "(ii)", buffer_x, buffer_y);
}

%% }}}
